<!-- HTML header for doxygen 1.8.3.1-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.3.1"/>
<title>AngelScript: Registering a reference type</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script type="test/javascript" src="touch.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
  $(window).load(resizeHeight);
</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
  $(document).ready(function() { searchBox.OnSelectItem(0); });
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="aslogo_small.png"/></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">AngelScript
   </div>
  </td>
   <td>        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.png"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
          </span>
        </div>
</td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.3.1 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('doc_reg_basicref.html','');});
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark">&#160;</span>Macros</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark">&#160;</span>Pages</a></div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="header">
  <div class="headertitle">
<div class="title">Registering a reference type </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>The basic reference type should be registered with the following behaviours: <a class="el" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a0b3db16eea35213b6f41f8d19dc1bd4c">asBEHAVE_FACTORY</a>, <a class="el" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a1dfa5b72ad69a7bf70636d4fcb1b1d84">asBEHAVE_ADDREF</a>, and <a class="el" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a7134ce13c81967191af401a1e5170a0c">asBEHAVE_RELEASE</a>.</p>
<div class="fragment"><div class="line"><span class="comment">// Registering the reference type</span></div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a29c6c087c8c5b5cdb6271cfd161cc5a6" title="Registers a new object type.">RegisterObjectType</a>(<span class="stringliteral">&quot;ref&quot;</span>, 0, <a class="code" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aa9450e038342b36c745858d2e5ae4b861" title="A reference type.">asOBJ_REF</a>); assert( r &gt;= 0 );</div>
</div><!-- fragment --><dl class="section see"><dt>See Also</dt><dd>The <a class="el" href="doc_addon_any.html">any</a> add-on for an example of a reference type.</dd>
<dd>
<a class="el" href="doc_gc_object.html">Garbage collected objects</a>, <a class="el" href="doc_adv_class_hierarchy.html">Class hierarchies</a>, <a class="el" href="doc_adv_scoped_type.html">Registering a scoped reference type</a>, and <a class="el" href="doc_adv_single_ref_type.html">Registering a single-reference type</a> for more advanced types.</dd></dl>
<h1><a class="anchor" id="doc_reg_basicref_1"></a>
Factory function</h1>
<p>The factory function is the one that AngelScript will use to instantiate objects of this type when a variable is declared. It is responsible for allocating and initializing the object memory.</p>
<p>The default factory function doesn't take any parameters and should return an object handle for the new object. Make sure the object's reference counter is accounting for the reference being returned by the factory function, so that the object is properly released when all references to it are removed.</p>
<div class="fragment"><div class="line">CRef::CRef()</div>
<div class="line">{</div>
<div class="line">    <span class="comment">// Let the constructor initialize the reference counter to 1</span></div>
<div class="line">    refCount = 1;</div>
<div class="line">}</div>
<div class="line"></div>
<div class="line">CRef *Ref_Factory()</div>
<div class="line">{</div>
<div class="line">    <span class="comment">// The class constructor is initializing the reference counter to 1</span></div>
<div class="line">    <span class="keywordflow">return</span> <span class="keyword">new</span> CRef();</div>
<div class="line">}</div>
<div class="line"></div>
<div class="line"><span class="comment">// Registering the factory behaviour</span></div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#ad69bc821a7f1120369c1bd9526f41b9c" title="Registers a behaviour for the object type.">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;ref&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a0b3db16eea35213b6f41f8d19dc1bd4c" title="Factory.">asBEHAVE_FACTORY</a>, <span class="stringliteral">&quot;ref@ f()&quot;</span>, <a class="code" href="angelscript_8h.html#a78f8f2c7f1c88b12e74a5ac47b4184ae" title="Returns an asSFuncPtr representing the function specified by the name.">asFUNCTION</a>(Ref_Factory), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4" title="A cdecl function.">asCALL_CDECL</a>); assert( r &gt;= 0 );</div>
</div><!-- fragment --><p>You may also register factory functions that take parameters, which may then be used when initializing the object.</p>
<p>The factory function must be registered as a global function, but can be implemented as a static class method, common global function, or a global function following the generic calling convention.</p>
<p>See also <a class="el" href="doc_reg_basicref.html#doc_reg_basicref_4">List factory function</a>.</p>
<h1><a class="anchor" id="doc_reg_basicref_2"></a>
Addref and release behaviours</h1>
<div class="fragment"><div class="line"><span class="keywordtype">void</span> CRef::Addref()</div>
<div class="line">{</div>
<div class="line">    <span class="comment">// Increase the reference counter</span></div>
<div class="line">    refCount++;</div>
<div class="line">}</div>
<div class="line"></div>
<div class="line"><span class="keywordtype">void</span> CRef::Release()</div>
<div class="line">{</div>
<div class="line">    <span class="comment">// Decrease ref count and delete if it reaches 0</span></div>
<div class="line">    <span class="keywordflow">if</span>( --refCount == 0 )</div>
<div class="line">        <span class="keyword">delete</span> <span class="keyword">this</span>;</div>
<div class="line">}</div>
<div class="line"></div>
<div class="line"><span class="comment">// Registering the addref/release behaviours</span></div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#ad69bc821a7f1120369c1bd9526f41b9c" title="Registers a behaviour for the object type.">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;ref&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a1dfa5b72ad69a7bf70636d4fcb1b1d84" title="AddRef.">asBEHAVE_ADDREF</a>, <span class="stringliteral">&quot;void f()&quot;</span>, <a class="code" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6" title="Returns an asSFuncPtr representing the class method specified by class and method name...">asMETHOD</a>(CRef,AddRef), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96" title="A thiscall class method.">asCALL_THISCALL</a>); assert( r &gt;= 0 );</div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#ad69bc821a7f1120369c1bd9526f41b9c" title="Registers a behaviour for the object type.">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;ref&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a7134ce13c81967191af401a1e5170a0c" title="Release.">asBEHAVE_RELEASE</a>, <span class="stringliteral">&quot;void f()&quot;</span>, <a class="code" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6" title="Returns an asSFuncPtr representing the class method specified by class and method name...">asMETHOD</a>(CRef,Release), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96" title="A thiscall class method.">asCALL_THISCALL</a>); assert( r &gt;= 0 );</div>
</div><!-- fragment --><p>If the instances of this object will be shared between multiple threads, remember to guarantee that the reference counter is thread safe by making the increments and decrements with atomic instructions.</p>
<dl class="section see"><dt>See Also</dt><dd><a class="el" href="doc_adv_multithread.html">Multithreading</a></dd></dl>
<h1><a class="anchor" id="doc_reg_nocount"></a>
Reference types without reference counting</h1>
<p>If the application provides its own memory management that isn't based on reference counting, then it is possible to register the type without the addref and release behaviours if the flag, asOBJ_NOCOUNT is informed in the call to RegisterObjectType, i.e.</p>
<div class="fragment"><div class="line"><span class="comment">// Registering the reference type</span></div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a29c6c087c8c5b5cdb6271cfd161cc5a6" title="Registers a new object type.">RegisterObjectType</a>(<span class="stringliteral">&quot;ref&quot;</span>, 0, <a class="code" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aa9450e038342b36c745858d2e5ae4b861" title="A reference type.">asOBJ_REF</a> | <a class="code" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aad8b12da6bf9cd48990d48c2ddf13584d" title="The type doesn&#39;t use reference counting. Only valid for reference types.">asOBJ_NOCOUNT</a>); assert( r &gt;= 0 );</div>
</div><!-- fragment --><p>Without the addref and release behaviours the application must be careful to not destroy any objects that may potentially still be referenced by the script engine, e.g. in a global variable, or other location.</p>
<p>Unless the objects are guaranteed to stay alive as long as the script engine is instantiated, you may want to consider disabling global variables with engine property <a class="el" href="angelscript_8h.html#a53c2e8a74ade77c928316396394ebe0fab81c81f4fdeb616dd6487da48a0c3456">asEP_DISALLOW_GLOBAL_VARS</a>. This will make it much easier for the application to know where references to the objects are kept. An alternative to disabling all global variables, is to selectively disallow only the global variables, that can eventually store a reference to the object type. This can be done by <a class="el" href="classas_i_script_module.html#a87e29773f7e6f2980d75288faaa74d02">enumerating the compiled global variables</a> after script has been built and giving an error to the user in case he includes a variable he shouldn't.</p>
<h1><a class="anchor" id="doc_reg_basicref_4"></a>
List factory function</h1>
<p>The list factory function is a special <a class="el" href="doc_reg_basicref.html#doc_reg_basicref_1">factory function</a> that can be registered to allow a type to be created from an initialization list. The list factory function takes only a single pointer as argument. AngelScript will pass a pointer to the initialization list buffer in that argument. The buffer will contain all the values necessary to create and initialize the object.</p>
<p>In order for the script engine to know what information must be placed in the buffer the application must provide the list pattern when registering the list factory. The list pattern is declared with a special syntax involving datatypes and the following tokens: {, }, ?, repeat, and repeat_same.</p>
<p>The tokens { } are used to declare that the list pattern expects a list of values or a sublist of values. The repeat token is used to signal that the next type or sub list can be repeated 0 or more times. The repeat_same token is similar to repeat except that it also tells the compiler that every time the same list is repeated it should have the same length. Any data type can be used in the list pattern, as long as it can be passed by value. When a variable type is desired the token ? can be used.</p>
<p>Here's a couple of examples for registering list factories with list patterns:</p>
<div class="fragment"><div class="line"><span class="comment">// The array type can be initialized for example with: intarray a = {1,2,3};</span></div>
<div class="line">engine-&gt;<a class="code" href="classas_i_script_engine.html#ad69bc821a7f1120369c1bd9526f41b9c" title="Registers a behaviour for the object type.">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;intarray&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5aea078bc3b877ce33a2335e78ddb4938d" title="Factory used exclusively for initialization lists.">asBEHAVE_LIST_FACTORY</a>, </div>
<div class="line">  <span class="stringliteral">&quot;intarray@ f(int &amp;in) {repeat int}&quot;</span>, ...);</div>
<div class="line"></div>
<div class="line"><span class="comment">// The dictionary type can be initialized with: dictionary d = {{&#39;a&#39;,1}, {&#39;b&#39;,2}, {&#39;c&#39;,3}};</span></div>
<div class="line">engine-&gt;<a class="code" href="classas_i_script_engine.html#ad69bc821a7f1120369c1bd9526f41b9c" title="Registers a behaviour for the object type.">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;dictionary&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5aea078bc3b877ce33a2335e78ddb4938d" title="Factory used exclusively for initialization lists.">asBEHAVE_LIST_FACTORY</a>, </div>
<div class="line">  <span class="stringliteral">&quot;dictionary @f(int &amp;in) {repeat {string, ?}}&quot;</span>, ...);</div>
<div class="line">  </div>
<div class="line"><span class="comment">// The grid type can be initialized with: grid a = {{1,2},{3,4}};</span></div>
<div class="line">engine-&gt;RgisterObjectBehaviour(<span class="stringliteral">&quot;grid&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5aea078bc3b877ce33a2335e78ddb4938d" title="Factory used exclusively for initialization lists.">asBEHAVE_LIST_FACTORY</a>,</div>
<div class="line">  <span class="stringliteral">&quot;grid @f(int &amp;in) {repeat {repeat_same int}}&quot;</span>, ...);</div>
</div><!-- fragment --><p>The list buffer passed to the factory function will be populated using the following rules:</p>
<ul>
<li>Whenever the pattern expects a repeat, the buffer will contain a 32bit integer with the number of repeated values that will come afterwards</li>
<li>Whenever the pattern expects a ?, then the buffer will contain a 32bit integer representing the typeId of the value that comes after.</li>
<li>Whenever the pattern expects a reference type, the buffer will contain a pointer to the object</li>
<li>Whenever the pattern expects a value type, the buffer will contain the object itself</li>
<li>All values in the buffer will be aligned to a 32bit boundary, unless the size of the value placed in the buffer is smaller than 32bits.</li>
</ul>
<dl class="section see"><dt>See Also</dt><dd><a class="el" href="doc_addon_array.html">array template object</a> and <a class="el" href="doc_addon_dict.html">dictionary object</a> for example implementations of list factories.</dd></dl>
<h1><a class="anchor" id="doc_reg_noinst"></a>
Registering an uninstantiable reference type</h1>
<p>Sometimes it may be useful to register types that cannot be instantiated by the scripts, yet can be interacted with. You can do this by registering the type as a normal reference type, but omit the registration of the factory behaviour. You can later register global properties, or functions that allow the scripts to access objects created by the application via object handles.</p>
<p>This would be used when the application has a limited number of objects available and doesn't want to create new ones. For example singletons, or pooled objects. </p>
</div></div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated on Sun Dec 18 2016 12:35:29 for AngelScript by
    <a href="http://www.doxygen.org/index.html">
    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.3.1 </li>
  </ul>
</div>
</body>
</html>
